home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 23 / CU Amiga - Super CD-ROM 23 (June 1998).iso / CUCD / Graphics / STIMP_noise / source / ppmvecmedian / ppmvecmedian.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-01-31  |  4.1 KB  |  194 lines

  1.  
  2. /************************************************************************/
  3. #define OP_NAME      "ppmvecmedian"
  4. #define VERSION      "1.03"
  5. #define DATE         "31.01.98"
  6. #define AUTHOR       "Stefan Diener"
  7. /************************************************************************/
  8.  
  9. #include <stdio.h>
  10. #include <stdarg.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <sys/types.h>
  14.  
  15. #include <STIMP/ppm.c>
  16.  
  17. struct PPM_Info source, desti;
  18. static int m, n;
  19. static int edge=1;
  20.  
  21. #define quad(x) (x)*(x)
  22.  
  23. void Do_It(void)
  24. {
  25.   int i, j, k, l, posx, poss, index, su, mini, abstand1, abstand2, x, y;
  26.   int r[81], g[81], b[81];
  27.   unsigned char *srcR,*srcG, *srcB, *dstR, *dstG, *dstB;
  28.  
  29.   /* Zeiger auf Bilddaten holen */
  30.   srcR=source.redData;
  31.   srcG=source.greenData;
  32.   srcB=source.blueData;
  33.   dstR=desti.redData;
  34.   dstG=desti.greenData;
  35.   dstB=desti.blueData;
  36.  
  37.   /* gleiches maxval */
  38.   desti.maxval=source.maxval;
  39.   
  40.   /* Schleife ueber alle Punkte des Zielbildes */
  41.   /* => Randproblem unterdruecken */
  42.   for (i=edge; i<(n-edge); i++)
  43.     for (l=edge; l<(m-edge); l++)
  44.     {
  45.       index=l*n+i;   /* Index im Quellbild */
  46.  
  47.       /* Filtermaske abarbeiten */
  48.       posx=0;
  49.       for (j=-edge; j<=edge; j++)
  50.         for (k=-edge; k<=edge; k++)
  51.         {
  52.           poss=index+j*n+k;
  53.           r[posx]=srcR[poss];
  54.           g[posx]=srcG[poss];
  55.           b[posx]=srcB[poss];
  56.           posx++;
  57.         }
  58.  
  59.       /* minimale Summe der Quadrate finden */
  60.       mini=6000000;
  61.       posx=0;
  62.       for (k=0; k<=4*edge*(edge+1); k++)
  63.       {
  64.         su=0;
  65.         for (j=0; j<=4*edge*(edge+1); j++) su+=quad(r[k]-r[j])+quad(g[k]-g[j])+quad(b[k]-b[j]);
  66.         if (su<=mini)
  67.         {
  68.           if (su==mini)
  69.           {
  70.             x=posx/(2*edge+1)-edge;
  71.             y=posx%(2*edge+1)-edge;
  72.             abstand2=x*x+y*y;
  73.             if (abstand2<abstand1)
  74.             {
  75.               abstand1=abstand2;
  76.               posx=k;
  77.             }
  78.           }
  79.           else
  80.           {
  81.             mini=su;
  82.             posx=k;
  83.             x=posx/(2*edge+1)-edge;
  84.             y=posx%(2*edge+1)-edge;
  85.             abstand1=x*x+y*y;
  86.           }
  87.         }
  88.       }
  89.  
  90.      /* entsprechenden Punkt ins Zielbild kopieren */
  91.       j=posx/(2*edge+1)-edge;
  92.       k=posx%(2*edge+1)-edge;
  93.       posx=(l-edge)*(n-2*edge)+i-edge;
  94.       poss=index+j*n+k;
  95.       dstR[posx]=srcR[poss];
  96.       dstG[posx]=srcG[poss];
  97.       dstB[posx]=srcB[poss];
  98.     }
  99. }
  100.  
  101. int main(int argc,char **argv)
  102. /* Hauptprogramm */
  103. {
  104.   int i;
  105.  
  106.   /* offizielle Begruessung */
  107.   PrintOpening(argc,argv);
  108.  
  109.   /* Uebergebene Parameter auswerten */
  110.   for (i=1; i<argc; i++)
  111.   {
  112.     if ((argv[i][0]=='-') && argv[i][1])
  113.     {
  114.       switch (argv[i][1])
  115.       {
  116.         case '3': edge=1;
  117.                       break;
  118.  
  119.         case '5': edge=2;
  120.                       break;
  121.  
  122.         case '7': edge=3;
  123.                       break;
  124.  
  125.         case '9': edge=4;
  126.                       break;
  127.  
  128.         case 'v': beVerbose=FALSE;
  129.                       break;
  130.  
  131.         default: PrintMessage("Unknown parameter: %s", argv[i]);
  132.                      Hilfe();
  133.                      exit(-1);
  134.                      break;
  135.       }
  136.     }
  137.  
  138.     if (argv[i][0]=='+')
  139.     {
  140.       switch (argv[i][1])
  141.       {
  142.         case 'v': beVerbose=TRUE;
  143.                       break;
  144.  
  145.         default: PrintMessage("Unknown parameter: %s", argv[i]);
  146.                      Hilfe();
  147.                      exit(-1);
  148.                      break;
  149.       }
  150.     }
  151.   }
  152.  
  153.   /* Mindestzahl der Argumente pruefen */
  154.   if (argc<3)
  155.   {
  156.     PrintMessage("Wrong number of arguments !");
  157.     Hilfe();
  158.     exit(-1);
  159.   }
  160.  
  161.   /* Anzahl der Dateinamen überprüfen */
  162.   if (FilenameCount(argc, argv)!=2)
  163.   {
  164.     PrintMessage("Wrong number of file names !");
  165.     Hilfe();
  166.     exit(-1);
  167.   }
  168.  
  169.   if (ReadPPMFile(GetFilename(1,argc,argv),&source)==0)
  170.   {
  171.     m=source.height;
  172.     n=source.width;
  173.  
  174.     if ((m<=2*edge) || (n<=2*edge)) PrintMessage("The source picture is too small !!!");
  175.     else
  176.     {
  177.       if (CreatePPMArray(m-2*edge,n-2*edge,&desti)==0)
  178.       {
  179.         PrintMessage("Working ...");
  180.         Do_It();
  181.  
  182.         WritePPMFile(GetFilename(2,argc,argv),&desti);
  183.         FreePPMArray(&desti);
  184.       }
  185.     }
  186.  
  187.     FreePPMArray(&source);
  188.   }
  189.  
  190.   PrintClosing();
  191.   exit(0);
  192. }
  193.  
  194.